//pub mod index;
//pub use index::Index;

/// 依据条件获取结果记录
/// ```
/// record_list!(); //后台模型默认
/// ```
#[macro_export]
macro_rules! record_list {
    () => {
        /// 用户列表
        pub async fn list(db: &Pool) -> anyhow::Result<JsonPager<ModelRow>> {
            Self::set_pager::<ModelRow>(sqlx::query(&Self::get_query()).map(|r: PgRow| {
                Self::get_row_filter(&r)
            }).fetch_all(db.as_ref()).await)
        }
    }
}

/// 展开数据库字段, 生成默认模型
/// (单行记录, 字段列表)
/// ```
/// unfold_fields!(row, {id => i32, name => String,})
/// ```
/// (单行记录, 字段列表, 浮点字段)
/// ```
/// unfold_fields!(row, {id => i32, name => String,}, {money,})
/// ```
/// (单行记录, 字段列表, 浮点字段, 日期时间字段)
/// ```
/// unfold_fields!(row, {id => i32, name => String,}, {money,}, {created, updated,})
/// ```
/// (单行记录, 字段列表, 浮点字段, 日期时间字段, 日期字段)
/// ```
/// unfold_fields!(row, {id => i32, name => Stirng,}, {money,}, {created, updated,}, {birth,})
/// ```
/// (单行记录, 字段列表, 浮点字段, 日期时间字段, 日期字段, ip字段)
/// ```
/// unfold_fields!(row, {id => i32, name => Stirng,}, {money,}, {created, updated,}, {birth,}, {login_ip,})
/// ```
#[macro_export]
macro_rules! unfold_fields {
    ($r: expr, {$($key: ident => $type: tt,)+}) => {{
        $(let $key: $type = if let Ok(v) = $r.try_get::<$type, &'static str>(stringify!($key)) { v } else { $type::default() };)+
        ModelRow {
            $($key,)+
        }
    }};
    ($r: expr, {$($key: ident => $type: tt,)+}, {$($float_field: ident,)+}) => {{
        $(let $key: $type = if let Ok(v) = $r.try_get::<$type, &'static str>(stringify!($key)) { v } else { $type::default() };)+
        $(let $float_field: f32 = if let Ok(v) = $r.try_get::<sqlx::types::BigDecimal, &'static str>(stringify!($float_field)) {
            v.to_f32().unwrap()
        } else { 0.0 };)+
        ModelRow {
            $($key,)+
            $($float_field,)+
        }
    }};
    ($r: expr, {$($key: ident => $type: tt,)+}, {$($float_field: ident,)*}, {$($datetime_field: ident,)+}) => {{
        $(let $key: $type = if let Ok(v) = $r.try_get::<$type, &'static str>(stringify!($key)) { v } else { $type::default() };)+
        $(let $float_field: f32 = if let Ok(v) = $r.try_get::<sqlx::types::BigDecimal, &'static str>(stringify!($float_field)) {
            v.to_f32().unwrap()
        } else { 0.0 };)*
        $(let $datetime_field: String = if let Ok(v) = $r.try_get::<sqlx::types::chrono::DateTime<sqlx::types::chrono::Utc>, &'static str>(stringify!($datetime_field)) {
            v.format("%Y-%m-%d %H:%M").to_string()
        } else { "".to_owned() };)+
        ModelRow {
            $($key,)+
            $($float_field,)+
            $($datetime_field,)+
        }
    }};
    ($r: expr, {$($key: ident => $type: tt,)+}, {$($float_field: ident,)*}, {$($datetime_field: ident,)*}, {$($date_field: ident,)+}) => {{
        $(let $key: $type = if let Ok(v) = $r.try_get::<$type, &'static str>(stringify!($key)) { v } else { $type::default() };)+
        $(let $float_field: f32 = if let Ok(v) = $r.try_get::<sqlx::types::BigDecimal, &'static str>(stringify!($float_field)) {
            v.to_f32().unwrap()
        } else { 0.0 };)*
        $(let $datetime_field: String = if let Ok(v) = $r.try_get::<sqlx::types::chrono::DateTime<sqlx::types::chrono::Utc>, &'static str>(stringify!($datetime_field)) {
            v.format("%Y-%m-%d %H:%M").to_string()
        } else { "".to_owned() };)*
        $(let $date_field: String = if let Ok(v) = $r.try_get::<sqlx::types::chrono::NaiveDate, &'static str>(stringify!($date_field)) { 
            v.to_string()
        } else { "".to_owned() };)+
        ModelRow {
            $($key,)+
            $($float_field,)*
            $($datetime_field,)*
            $($date_field,)+
        }
    }};
    ($r: expr, {$($key: ident => $type: tt,)+}, {$($float_field: ident,)*}, {$($datetime_field: ident,)*}, {$($date_field: ident,)*}, {$($ip_field: ident,)+}) => {{
        $(let $key: $type = if let Ok(v) = $r.try_get::<$type, &'static str>(stringify!($key)) { v } else { $type::default() };)+
        $(let $float_field: f32 = if let Ok(v) = $r.try_get::<sqlx::types::BigDecimal, &'static str>(stringify!($float_field)) {
            v.to_f32().unwrap()
        } else { 0.0 };)*
        $(let $datetime_field: String = if let Ok(v) = $r.try_get::<sqlx::types::chrono::DateTime<sqlx::types::chrono::Utc>, &'static str>(stringify!($datetime_field)) {
            v.format("%Y-%m-%d %H:%M").to_string()
        } else { "".to_owned() };)*
        $(let $date_field: String = if let Ok(v) = $r.try_get::<sqlx::types::chrono::NaiveDate, &'static str>(stringify!($date_field)) { 
            v.to_string()
        } else { "".to_owned() };)*
        $(let $ip_field: String = if let Ok(v) = $r.try_get::<sqlx::types::ipnetwork::IpNetwork, &'static str>(stringify!($ip_field)) { 
            v.to_string()
        } else { "".to_owned() };)+
        ModelRow {
            $($key,)+
            $($float_field,)*
            $($datetime_field,)*
            $($date_field,)*
            $($ip_field,)+
        }
    }};
}

/// 银行列表
pub mod bank;
pub use bank::Bank;

/// 城市省份列表
pub mod province;
pub use province::Province;

/// 城市列表
pub mod city;
pub use city::City;

/// 用户信息
pub mod user;
pub use user::{User};

/// 用户资金表
pub mod user_account;
pub use user_account::UserAccount;

/// 用户详情
pub mod user_detail;
pub use user_detail::UserDetail;

/// 用户银行卡
pub mod user_card;
pub use user_card::UserCard;

/// 充值记录
pub mod recharge;
pub use recharge::Recharge;

/// 提现记录
pub mod withdraw;
pub use withdraw::Withdraw;

/// 账变记录
pub mod account_change;
pub use account_change::AccountChange;

/// 后台菜单
pub mod menu;
pub use menu::Menu;

/// 后台用户角色
pub mod admin_role;
pub use admin_role::AdminRole;

/// 后台用户管理
pub mod admin;
pub use admin::Admin;

/// 后台用户日志
pub mod admin_log;
pub use admin_log::AdminLog;
